﻿// ===============================================================================
//  Copyright © ymind.net. All rights reserved .
//  官方网站：http://ymind.net/
//  版权所有：彦铭工作室 老陈出品
// ===============================================================================

using System;
using System.Collections;
using System.Configuration;
using System.Xml;
using Lcsoft.UrlRewriter.Actions;
using Lcsoft.UrlRewriter.Configuration;
using Lcsoft.UrlRewriter.Utilities;

namespace Lcsoft.UrlRewriter.Parsers
{
	/// <summary>
	/// 解析 &lt;if&gt; 标记。
	/// </summary>
	public class IfConditionActionParser : RewriteActionParserBase
	{
		/// <summary>
		/// 获取动作名。
		/// </summary>
		public override string Name
		{
			get { return Constants.ElementIf; }
		}

		/// <summary>
		/// 获取一个值，该值指示当前动作是否允许嵌套动作。
		/// </summary>
		public override bool AllowsNestedActions
		{
			get { return true; }
		}

		/// <summary>
		/// 获取一个值，该值指示当前动作是否允许包含 Attribute 属性。
		/// </summary>
		public override bool AllowsAttributes
		{
			get { return true; }
		}

		/// <summary>
		/// 执行地址重写动作解析。
		/// </summary>
		/// <param name="node">包含要解析的动作信息的。</param>
		/// <param name="config">地址重写配置信息。</param>
		/// <returns>返回地址重写动作的实例。</returns>
		public override IRewriteAction Parse(XmlNode node, RewriterConfiguration config)
		{
			if (node == null) throw new ArgumentNullException("node");

			if (config == null) throw new ArgumentNullException("config");

			var rule = new ConditionalAction();

			var negative = (node.LocalName == Constants.ElementUnless);

			this.ParseConditions(node, rule.Conditions, negative, config);

			_ReadActions(node, rule.Actions, config);

			return rule;
		}

		private static void _ReadActions(XmlNode node, IList actions, RewriterConfiguration config)
		{
			if (node == null) throw new ArgumentNullException("node");

			if (config == null) throw new ArgumentNullException("config");

			var childNode = node.FirstChild;

			while (childNode != null)
			{
				if (childNode.NodeType == XmlNodeType.Element)
				{
					var parsers = config.ActionParsers.GetParsers(childNode.LocalName);

					if (parsers == null) continue;

					var parsed = false;

					foreach (IRewriteActionParser parser in parsers)
					{
						var action = parser.Parse(childNode, config);

						if (action == null) continue;

						parsed = true;
						actions.Add(action);
					}

					if (!parsed) throw new ConfigurationErrorsException(MessageProvider.FormatString(Message.ElementNotAllowed, node.FirstChild.Name), node);
				}

				childNode = childNode.NextSibling;
			}
		}
	}
}
